package com.myjpa.service;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.myjpa.common.criteria.CriteriaUtils;
import com.myjpa.common.criteria.JacksonCriteria;
import com.myjpa.common.web.MapResponse;
import com.myjpa.common.web.PagedResponse;
import com.myjpa.entity.Order;
import com.myjpa.entity.QOrder;
import com.myjpa.repository.OrderRepository;
import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @author: yaoll
 * @date: 2020-09-04
 * @verison: 1.0
 */
@Service
public class OrderService {

	@Autowired
	private OrderRepository repository;

	@Autowired
	private CriteriaUtils criteriaUtils;


	private List<BooleanExpression> parse(JacksonCriteria criteria) {
		QOrder qt = QOrder.order;
		List<BooleanExpression> list = new LinkedList<>();
		ObjectNode object = criteria.getCriteria();
		if (object.has("containProduct")) {
			list.addAll(CriteriaUtils.parse(qt.items.any().productName, object.get("containProduct")));
		}
		return list;
	}

	public PagedResponse<Order> query(JacksonCriteria criteria) {
		PagedResponse<Order> query = criteriaUtils.query(QOrder.order, this::parse, criteria);
		PagedResponse<Order> resp = new PagedResponse<>();
		resp.setCount(query.getCount());
		List<Order> data = query.getData();
		if (data != null && data.size() > 0) {
			List<Order> models = new ArrayList<>(data.size());
			boolean withItems = criteria.withColumn("items");
			for (Order datum : data) {
				Order model = new Order();
				BeanUtils.copyProperties(datum, model, "items");
				if (withItems) {
					model.setItems(datum.getItems());
				}
				models.add(model);
			}
			resp.setData(models);
		}
		return resp;
	}

	@Transactional
	public MapResponse create(Order order) {
		repository.save(order);
		MapResponse resp = new MapResponse();
		resp.add("id", order.getId());
		return resp;
	}

	public MapResponse update(Order order) {
		repository.save(order);
		MapResponse resp = new MapResponse();
		resp.add("id", order.getId());
		return resp;
	}

	public MapResponse delete(Order order) {
		repository.deleteById(order.getId());
		return new MapResponse();
	}
}
